/**
 * ...
 * @author Franco Ponticelli
 */

package js;

import js.Dom;

class HDom
{
	public static function createElement(tagName : String, ?innerHTML : String, ?cssText : String)
	{
        var e = Lib.document.createElement(tagName);
        if (null != cssText) e.style.cssText = cssText;
        if (null != innerHTML) e.innerHTML = innerHTML;
        return e;
	}
	
	public static inline function byId(id : String)
	{
		return Lib.document.getElementById(id);
	}
	
	public static dynamic function getText(n : HtmlDom) {
		untyped getText = (document.documentElement.textContent != undefined) ?
			function(n) {
				var r = (n == null) ? '' : n.textContent;
				return r != null ? r : '';
			} : function(n) {
				var r = (n == null) ? '' : n.innerText;
				return r != null ? r : '';
			};
		return getText(n);
	}
	
	public static dynamic function setText(n : HtmlDom, content : String) {
		untyped setText = (untyped document.documentElement.textContent != undefined) ?
			function(n, content) {
				if (n == null) return;
				n.textContent = content;
			} : function(n, content) {
				if (n == null) return;
				n.innerText = content;
			};
		setText(n, content);
	}
	
	public static function create(html : String) {
		html = StringTools.trim(html);
		if (_cloneCache.exists(html))
			return _cloneCache.get(html).cloneNode(true);
		var c = _create, tag = null;
		if (re_tag.match(html) && DomCreator.creators.exists(re_tag.matched(1))) {
			var t = DomCreator.creators.get(re_tag.matched(1));
			if (Reflect.isFunction(t))
				c = t;
			else
				tag = t;
		}
		var nodes = c(html, tag).childNodes;
		var ret : HtmlDom = null;
		if (nodes.length == 1) {
			ret = nodes[0].parentNode.removeChild(nodes[0]);
		} else {
			ret = untyped js.Lib.document.createDocumentFragment();
            while (nodes.length > 0) {
                ret.appendChild(nodes[0]);
            }
		}
		
		_cloneCache.set(html, ret.cloneNode(true));
        return ret;
	}
	
	public static function hasClass(n : HtmlDom, className : String) {
		return (new EReg('(?:^|\\s+)' + className + '(?:\\s+|$)', '')).match(n.className);
	}
	
	public static function addClass(n : HtmlDom, className : String) {
		if (hasClass(n, className)) return;
		n.className = StringTools.trim([n.className, className].join(' '));
	}
	
	public static function removeClass(n : HtmlDom, className : String) {
		if (className == '' || className == null || !hasClass(n, className)) return;
		n.className = (new EReg('(?:^|\\s+)' + className + '(?:\\s+|$)', '')).replace(n.className, ' ');
		removeClass(n, className); // in case of multiple adjacent
	}
	
	public static function replaceClass(n : HtmlDom, oldC : String, newC : String) {
		addClass(n, newC);
		removeClass(n, oldC);
	}
	
	public static function toggleClass(n : HtmlDom, className : String) {
		if (hasClass(n, className))
			removeClass(n, className);
		else
			addClass(n, className);
	}
	
	public static function getClasses(n : HtmlDom) : Array<String>
	{
		return _classSplitter.split(n.className);
	}
	
	static function _create(html : String, tag : String) {
		if (tag == null)
			tag = 'div';
		var frag = _fragClones.get(tag);
		if (frag != null) {
			frag = frag.cloneNode(false);
		} else {
			frag = js.Lib.document.createElement(tag);
			_fragClones.set(tag, frag.cloneNode(false));
		}
		frag.innerHTML = html;
		return frag;
	}
	
	static var _cloneCache = new Hash<HtmlDom>();
	static var _fragClones= new Hash<HtmlDom>();
	static var re_tag = ~/<([a-z]+)/i;
	static var _classSplitter = ~/\s+/g;
	
	    /**
     * Adds a probe element to page dom tree, callbacks, removes the element
     *
     * @param {Element} dom Probing dom element
     * @param {function(Element)} callback
     */
		/*
    probe: function(dom, callback) {
        var target = doc.body;
        target.appendChild(dom);
        var result = callback(dom);
        target.removeChild(dom);
        return result;
    },
	*/
	
	public static function computedStyle(el : HtmlDom) : Style untyped
	{
		if (document.defaultView && document.defaultView.getComputedStyle)
		{
			return document.defaultView.getComputedStyle( el, null );
		} else {
			return el.currentStyle;
		}
	}

	/*
	    contains: function(parent, child) {
        try {
            if (parent.contains) return parent.contains(child);
            if (parent.compareDocumentPosition) return !!(parent.compareDocumentPosition(child) & 16);
        } catch (e) {}
        while ( child && child != parent ) {
            try { child = child.parentNode } catch(e) { child = null };
        }
        return parent == child;
    },
	
	    createStylesheet: function(code) {
        var style = doc.createElement('style');
        doc.getElementsByTagName('head')[0].appendChild(style);
        if (style.styleSheet) { //IE
            style.styleSheet.cssText = code;
        } else {
            style.appendChild(document.createTextNode(code));
        }
        return style;
    }
	
	uki.dom.Event = function( domEvent ) {
    domEvent = domEvent || {};
    this.domEvent = domEvent.domEvent || domEvent;

	for ( var i = uki.dom.props.length, prop; i; ){
		prop = uki.dom.props[ --i ];
		this[ prop ] = domEvent[ prop ];
	}
	
    // this.dataTransfer = new uki.dom.DataTransfer(domEvent);
};

uki.dom.Event.prototype = new function() {
    function returnTrue () {
        return true;
    }

    this.preventDefault = function() {
        var domEvent = this.domEvent;
        domEvent.preventDefault && domEvent.preventDefault();
        domEvent.returnValue = false;

        this.isDefaultPrevented = returnTrue;
    }

    this.stopPropagation = function() {
		var domEvent = this.domEvent;
		domEvent.stopPropagation && domEvent.stopPropagation();
		domEvent.cancelBubble = true;
		
		this.isPropagationStopped = returnTrue;
    }

    this.isDefaultPrevented = this.isPropagationStopped = uki.F;
}
*/
}